home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Acere (Card Game) / AcereÄ.sit / Acereƒ / WellStack.cp < prev    next >
Text File  |  1994-08-25  |  9KB  |  398 lines

  1. // ===========================================================================
  2. //    WellStack.cp                        ⌐1993 Metrowerks Inc. All rights reserved.
  3. // ===========================================================================
  4. //
  5. //    Class for an object that can draw itself and respond to mouse clicks
  6.  
  7. #ifdef PowerPlant_PCH
  8. #include PowerPlant_PCH
  9. #endif
  10.  
  11. #include "WellStack.h"
  12. #include "CardDeck.h"
  13. #include "AcereApp.h"
  14. #include "CTextDoc.h"
  15. #include <LView.h>
  16. #include <LStream.h>
  17. #include <PP_Messages.h>
  18. #include <UDrawingState.h>
  19.  
  20. extern CTextDoc *theDoc;
  21.  
  22. // ---------------------------------------------------------------------------
  23. //        Ñ CreatePaneStream [static]
  24. // ---------------------------------------------------------------------------
  25. //    Return a new Pane object initialized using data from a Stream
  26.  
  27. WellStack*
  28. WellStack::CreateWellStack(
  29.     LStream    *inStream)
  30. {
  31.     return (new WellStack(inStream));
  32. }
  33.  
  34.  
  35. // ---------------------------------------------------------------------------
  36. //        Ñ WellStack()
  37. // ---------------------------------------------------------------------------
  38. //    Default Constructor
  39.  
  40. WellStack::WellStack()
  41. {
  42.     mPaneID = 0;
  43.     mFrameSize.width = mFrameSize.height = 0;
  44.     mFrameLocation.h = mFrameLocation.v = 0;
  45.     mUserCon = 0;
  46.     
  47.     mFrameBinding.left =
  48.         mFrameBinding.top =
  49.         mFrameBinding.right =
  50.         mFrameBinding.bottom = false;
  51.     
  52.     mVisible = mActive = mEnabled = triState_Latent;
  53.  
  54.     mSuperView = nil;
  55.     itsCard.card = kNoCard;
  56.     
  57.     itsCards = nil;
  58.     
  59.     InitCards();
  60. }
  61.  
  62.  
  63. // ---------------------------------------------------------------------------
  64. //        Ñ WellStack(const WellStack&)
  65. // ---------------------------------------------------------------------------
  66. //    Copy Constructor
  67.  
  68. WellStack::WellStack(
  69.     const WellStack    &inOriginal)
  70. {
  71.                                     // Copy members of Original
  72.     mPaneID = inOriginal.mPaneID;
  73.     mFrameSize = inOriginal.mFrameSize;
  74.     mFrameLocation = inOriginal.mFrameLocation;
  75.     mFrameBinding = inOriginal.mFrameBinding;
  76.     mUserCon = inOriginal.mUserCon;
  77.     
  78.     mSuperView = nil;                // Copy is not inside any View
  79.     
  80.                                     // Pane properties. If Original has
  81.                                     //   property ON, Copy is Latent.
  82.     mVisible = inOriginal.mVisible;
  83.     if (mVisible == triState_On) {
  84.         mVisible = triState_Latent;
  85.     }
  86.  
  87.     mActive = inOriginal.mActive;
  88.     if (mActive == triState_On) {
  89.         mActive = triState_Latent;
  90.     }
  91.  
  92.     mEnabled = inOriginal.mEnabled;
  93.     if (mEnabled == triState_On) {
  94.         mEnabled = triState_Latent;
  95.     }
  96.  
  97.     
  98.     itsCards = nil;
  99.     InitCards();
  100. }
  101.  
  102.  
  103. // ---------------------------------------------------------------------------
  104. //        Ñ WellStack(SPaneInfo&)
  105. // ---------------------------------------------------------------------------
  106. //    Construct Pane from data in a struct
  107.  
  108. WellStack::WellStack(
  109.     const SPaneInfo    &inPaneInfo)
  110. {
  111.     InitPane(inPaneInfo);
  112. }
  113.  
  114.  
  115. // ---------------------------------------------------------------------------
  116. //        Ñ WellStack(LStream*)
  117. // ---------------------------------------------------------------------------
  118. //    Construct Pane from data in a Stream
  119.  
  120. WellStack::WellStack(
  121.     LStream    *inStream)
  122. {
  123.     SPaneInfo    thePaneInfo;
  124.     inStream->ReadData(&thePaneInfo, sizeof(SPaneInfo));
  125.     InitPane(thePaneInfo);
  126. }
  127.  
  128.  
  129. // ---------------------------------------------------------------------------
  130. //        Ñ InitPane
  131. // ---------------------------------------------------------------------------
  132. //    Initialize Pane from data in a struct
  133.  
  134. void
  135. WellStack::InitPane(
  136.     const SPaneInfo    &inPaneInfo)
  137. {
  138.     mPaneID = inPaneInfo.paneID;
  139.     mFrameSize.width = inPaneInfo.width;
  140.     mFrameSize.height = inPaneInfo.height;
  141.     mUserCon = inPaneInfo.userCon;
  142.     
  143.     mVisible = triState_Off;
  144.     if (inPaneInfo.visible) {
  145.         mVisible = triState_Latent;
  146.     }
  147.  
  148.     mActive = triState_Latent;
  149.  
  150.     mEnabled = triState_Off;
  151.     if (inPaneInfo.enabled) {
  152.         mEnabled = triState_Latent;
  153.     }
  154.     
  155.     mFrameBinding = inPaneInfo.bindings;
  156.     
  157.     mSuperView = nil;
  158.     
  159.     LView    *theSuperView = inPaneInfo.superView;
  160.     if (theSuperView == Default_SuperView) {
  161.         theSuperView = GetDefaultView();
  162.     }
  163.     PutInside(theSuperView);
  164.     if (theSuperView != nil) {
  165.         PlaceInSuperImageAt(inPaneInfo.left, inPaneInfo.top, false);
  166.         Boolean    expandHoriz = (inPaneInfo.width < 0);
  167.         Boolean    expandVert = (inPaneInfo.height < 0);
  168.         if (expandHoriz || expandVert) {
  169.             theSuperView->ExpandSubPane(this, expandHoriz, expandVert);
  170.         }
  171.     }
  172.     
  173.     
  174.     itsCards = nil;
  175.     InitCards();
  176. }
  177.  
  178.  
  179. // ---------------------------------------------------------------------------
  180. //        Ñ ~WellStack
  181. // ---------------------------------------------------------------------------
  182. //    Destructor
  183.  
  184. WellStack::~WellStack()
  185. {
  186.     PutInside(nil);
  187.     
  188.     if (sLastPaneClicked == this) {
  189.         sLastPaneClicked = nil;
  190.     }
  191. }
  192.  
  193.  
  194. // ---------------------------------------------------------------------------
  195. //        Ñ Draw
  196. // ---------------------------------------------------------------------------
  197. //    Try to draw contents of a Pane
  198. //
  199. //    inSuperDrawRgnH specifies, in Port coordinates, the portion of the
  200. //    Pane's SuperView that needs to be drawn. Specify nil to bypass
  201. //    the intersection test.
  202. //    
  203. //    This is a wrapper function which calls DrawSelf if it is proper for
  204. //    the Pane to draw. This means that:
  205. //        > Pane's Visible property is on
  206. //        > Pane can be focused
  207. //        > Pane's Frame is in QuickDraw space
  208. //        > Pane's Frame intersects inSuperDrawRgnH
  209.  
  210. void    WellStack::Draw(RgnHandle    inSuperDrawRgnH)
  211. {
  212.     Rect        frame, useFrame;
  213.     
  214.     short        i, maxItems;
  215.     
  216.     CardStruct    currentCard;
  217.     
  218.     maxItems = (short) itsCards->GetCount();
  219.  
  220.     if ( IsVisible()  &&
  221.          FocusDraw()  &&
  222.          CalcPortFrameRect(frame)  &&
  223.          ((inSuperDrawRgnH == nil) || RectInRgn(&frame, inSuperDrawRgnH)) )
  224.     {
  225.         if (maxItems == 0)
  226.         {
  227.             useFrame = frame;
  228.             useFrame.bottom = useFrame.top + 90;
  229.             EraseRect(&useFrame);
  230.             FrameRoundRect(&useFrame, 20, 20);
  231.             
  232.         }
  233.         for (i=1; i<= maxItems; i++)
  234.         {
  235.             itsCards->FetchItemAt(i, ¤tCard);
  236.             
  237.             if (i == maxItems)
  238.             {
  239.                 useFrame = frame;
  240.                 useFrame.top = frame.bottom - 90;
  241.                 
  242.             }
  243.             else
  244.             {
  245.                 useFrame = frame;
  246.                 useFrame.top = frame.top + (20  * (i-1));
  247.                 useFrame.bottom = useFrame.top + 20;
  248.             }
  249.             
  250.             if (currentCard.card == kNoCard)
  251.             {
  252.                 EraseRect(&frame);
  253.                 FrameRoundRect(&useFrame, 20, 20);
  254.             }
  255.             else
  256.             {
  257.                 
  258.                 theDeck->DrawCard(¤tCard, useFrame);
  259. //                FrameRoundRect(&useFrame, 20, 20);
  260.             }
  261.         }
  262.     }
  263. }
  264.  
  265. void    WellStack::InitCards(void)
  266. {
  267.     //    done when initializing only
  268.     
  269.     short     i, k;
  270.     long    thePaneID = GetPaneID();
  271.     
  272.     theDoc->theStacks[theDoc->currentStack] = this;
  273.     
  274.     if (itsCards != nil)                //    we're restarting a game╔
  275.         delete itsCards;
  276.     
  277.     itsCards = new LDynamicArray(sizeof(CardStruct));
  278.     mFrameSize.height -= 20;
  279.     
  280.     for (i=(thePaneID - 3001); i < NumCards; i += 8)
  281.     {
  282.         k = (short) theDeck->theCardPositions[i];
  283.         theDeck->GetCardInfo(k, &itsCard);
  284.         itsCard.itsOwner = this;
  285.         
  286. //        itsCards->InsertItemsAt(1, 9999, &itsCard);
  287.         
  288.         AddCardToWell(nil, &itsCard);
  289.         
  290. //        whichCard = k;
  291.     }
  292.     
  293.     theDoc->currentStack++;
  294.     
  295.     Draw(0L);
  296. }
  297.  
  298. Boolean    WellStack::CanDropOnSlot(CardStruct *draggedCard)
  299. {
  300.     //    stack behavior is different: we need a card of an opposite color
  301.     //    and an immediately lower value.
  302.     
  303.     if ((draggedCard->color != itsCard.color) && (draggedCard->card == (itsCard.card -1)))
  304.         return (true);
  305.     else
  306.         return (false);
  307. }
  308.  
  309.  
  310. void    WellStack::AddCardToWell(CardWell *whichWell, CardStruct *whichCard)
  311. {
  312.     whichCard->itsOwner = this; 
  313.     itsCards->InsertItemsAt(1, 9999, whichCard);
  314.     itsCard = *whichCard;
  315.     
  316.     AdjustFrame();
  317. }
  318.  
  319.  
  320. void    WellStack::RemoveCardFromWell(CardWell *whichWell, CardStruct *whichCard)
  321. {
  322.     short        i, maxItems;
  323.     CardStruct    tempCard;
  324.     
  325.     maxItems = (short) itsCards->GetCount();
  326.     
  327.     for (i = maxItems; i > 0; i--)
  328.     {
  329.         itsCards->FetchItemAt(i, &tempCard);
  330.         
  331.         if ((tempCard.suit == whichCard->suit) && 
  332.                     (tempCard.card == whichCard->card)) // right card
  333.         {
  334.             itsCards->RemoveItemsAt(1, i);
  335.             
  336.             if (i == maxItems)    //    need to update "top" card
  337.                     
  338.             {
  339.                 maxItems = (short) itsCards->GetCount();
  340.                 
  341.                 if (maxItems == 0)
  342.                     itsCard.card = kNoCard;
  343.                 else
  344.                     itsCards->FetchItemAt(maxItems, &itsCard);
  345.             }
  346.             AdjustFrame();
  347.             break;        //    exit for loop
  348.         }
  349.     }
  350.     
  351. }
  352.  
  353. void    WellStack::AdjustFrame(void)
  354. {
  355.         short        maxItems, difference;
  356.         Rect        frame;
  357.         RgnHandle    newRgn, oldRgn, saveClipRgn;
  358.         
  359.     oldRgn = NewRgn();
  360.     OpenRgn();
  361.     CalcPortFrameRect(frame);
  362.     FrameRoundRect(&frame, 20, 20);
  363.     CloseRgn(oldRgn);
  364.  
  365.     newRgn = NewRgn();
  366.         
  367.     difference = mFrameSize.height;
  368.      
  369.     maxItems = (short) itsCards->GetCount();
  370.     mFrameSize.height = 70 + (20 * maxItems);
  371.     
  372.     difference -= mFrameSize.height;
  373.     
  374.     if (difference > 0)
  375.     {
  376.         //    we need to clean up
  377.         
  378.         CalcPortFrameRect(frame);
  379.         
  380.         OpenRgn();
  381.         FrameRoundRect(&frame, 20, 20);
  382.         CloseRgn(newRgn);
  383.         
  384. //        DiffRgn(newRgn,oldRgn,newRgn);
  385.         DiffRgn(oldRgn, newRgn, newRgn);
  386.         
  387.         saveClipRgn = NewRgn();
  388.         
  389.         GetClip(saveClipRgn);
  390.         SetClip(newRgn);
  391.         EraseRgn(newRgn);
  392.         SetClip(saveClipRgn);
  393.         DisposeRgn(saveClipRgn);
  394.     }
  395.     DisposeRgn(newRgn);
  396.     DisposeRgn(oldRgn);
  397. }
  398.